package com.c39.otc.open.api.app;

import com.c39.cloud.rbac.facade.AppFacade;
import com.c39.cloud.rbac.facade.AuthFacade;
import com.c39.cloud.rbac.model.app.AppVO;
import com.c39.cloud.rbac.model.auth.AuthAppDTO;
import com.c39.otc.open.api.AppSessionTemplate;
import com.c39.otc.open.api.app.request.AccessTokenRequest;
import com.c39.otc.open.api.app.response.AccessTokenResponse;
import com.cqfan.cloud.dubbo.common.config.DubboConfig;
import com.cqfan.cloud.framework.base.PagedResult;
import com.cqfan.cloud.framework.base.Result;
import com.cqfan.cloud.framework.global.LogicI18nException;
import com.cqfan.cloud.framework.jwt.component.JwtComponent;
import com.cqfan.cloud.framework.redis.client.RedisFacade;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.Instant;
import java.util.List;

/**
 * 应用模块
 * @author JiaLing.FanX
 * @version 1.0
 * @description: TODO
 * @date 2025/9/10 17:05
 */

@Slf4j
@RestController
@RequestMapping("/v1/app")
public class AppController {

    @Resource
    private AppSessionTemplate appSessionTemplate;

    @Resource
    private AppFacade appFacade;

    @Resource
    private JwtComponent jwtComponent;

    /**
     * 获取access_token
     * @param accessTokenRequest
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getAccessToken", name = "getAccessToken", method = RequestMethod.POST)
    public Result<AccessTokenResponse> getAccessToken(@RequestBody @Valid AccessTokenRequest accessTokenRequest) throws Exception  {
            // 基础参数验证
            if (accessTokenRequest == null) {
                log.warn("AccessToken请求参数为空");
                return Result.fail("请求参数不能为空");
            }

            String requestAppId = accessTokenRequest.getAppId();
            String requestAppSecret = accessTokenRequest.getAppSecret();

            if (Strings.isNullOrEmpty(requestAppId) || Strings.isNullOrEmpty(requestAppSecret)) {
                return Result.fail("应用ID和密钥不能为空");
            }

            // 获取应用列表
            PagedResult<List<AppVO>> pagedResult = appFacade.list();
            List<AppVO> appVOS = (List<AppVO>) pagedResult.getData();

            // 验证应用是否存在且凭证匹配
            AppVO matchedApp = findMatchedApp(appVOS, requestAppId, requestAppSecret);
            if (matchedApp == null) {
                log.warn("应用验证失败, appId: {}, 可用应用数量: {}", requestAppId,
                        appVOS != null ? appVOS.size() : 0);
                throw new LogicI18nException("1000","应用ID或密钥验证失败");

            }
            log.info("应用验证成功, appId: {}", requestAppId);
            // 生成access token
            String accessToken = jwtComponent.createSid(requestAppId);
            AccessTokenResponse accessTokenResponse = new AccessTokenResponse();
            accessTokenResponse.setAccessToken(accessToken);


            int expiresIn = jwtComponent.getExpires();

            int timestampSeconds = (int) Instant.now().getEpochSecond();
            accessTokenResponse.setExpiresIn(timestampSeconds + expiresIn);

            // 存储session
            appSessionTemplate.putSign(accessTokenResponse.getAccessToken(),
                    accessTokenResponse.getAccessToken(),
                    timestampSeconds);

            log.info("AccessToken生成成功, appId: {}, token: {}", requestAppId,
                    accessToken.substring(0, Math.min(10, accessToken.length())) + "...");

            return Result.success(accessTokenResponse);
    }


    /**
     * 查找匹配的应用
     */
    private AppVO findMatchedApp(List<AppVO> appList, String requestAppId, String requestAppSecret) {
        if (appList == null) {
            return null;
        }

        return appList.stream()
                .filter(app -> app != null)
                .filter(app -> requestAppId.equals(app.getAppId()))
                .filter(app -> requestAppSecret.equals(app.getAppSecret()))
                .findFirst()
                .orElse(null);
    }
}
